package cn.meng.base.config;

import cn.meng.base.service.LoginService;
import cn.meng.base.service.PermissionService;
import cn.meng.base.service.RedisService;
import cn.meng.base.service.RoleService;
import cn.meng.base.vo.BusinessException;
import cn.meng.base.vo.PermissionVo;
import cn.meng.base.vo.RoleVo;
import cn.meng.base.vo.UserVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 自定义Realm
 * 具体两种角色：  管理员 ： root     超级管理员 ： super
 * 三种权限： 新增：add     修改：update    删除：delete
 */

public class UserRealm extends AuthorizingRealm {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 注入对应的service类，获取用户信息，权限信息
     * @param principalCollection
     * @return
     */
    @Autowired
    LoginService loginService;
    @Autowired
    RoleService roleService;
    @Autowired
    PermissionService permissionService;
    @Autowired
    RedisService redis;

    @Override
    //授权方法
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权方法==》doGetAuthorizationInfo");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        UserVo user = (UserVo) subject.getPrincipal();
        String pk_role = user.getPkRole();
        RoleVo role = roleService.queryRole(pk_role);
        List<PermissionVo> permissions = permissionService.queryPermission(pk_role);
        try {
            if(null == user || null == role || null ==permissions) {
                throw new BusinessException(500,"授权失败，请检查");
            }
        } catch (BusinessException e) {
            log.error("cn.meng.base.config.UserRealm.doGetAuthorizationInfo   Line:65   授权失败，请检查");
        }
        //设置角色信息
        info.addRole(role.getRoleValue());
        //设置所有权限信息
        for (PermissionVo permission : permissions) {
            info.addStringPermission(permission.getPermission_value());
        }
        //返回权限信息
        return info;
    }


    @Override
    //认证方法
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了认证方法==》doGetAuthenticationInfo");

        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
        String username = userToken.getUsername();
        UserVo user = loginService.queryUser(username);
        if(null == user) {
            log.error("cn.meng.base.config.UserRealm.doGetAuthenticationInfo   Line:86   用户不存在");
            return null;
        }
        RoleVo role = roleService.queryRole(user.getPkRole());
        try {
            if(null == role) {
                throw new BusinessException(401,"未找到对应的角色");
            }
        } catch (BusinessException e) {
            log.error("cn.meng.base.config.UserRealm.doGetAuthenticationInfo   Line:97   Error: " + e.getStatus() + e.getMessage());
        }
        //将角色信息设置到缓存中
        redis.cacheValue("role",role.getRoleValue(),60*60);
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

}
